package com.ragdollcat.thirdaicodegenerate.ai.strategy;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;

import com.ragdollcat.thirdaicodegenerate.constants.AppConstant;
import com.ragdollcat.thirdaicodegenerate.core.build.BuildVueProject;
import com.ragdollcat.thirdaicodegenerate.enums.ChatHistoryMessageTypeEnum;
import com.ragdollcat.thirdaicodegenerate.enums.StreamMessageTypeEnum;
import com.ragdollcat.thirdaicodegenerate.model.entity.User;
import com.ragdollcat.thirdaicodegenerate.service.ChatHistoryService;
import com.ragdollcat.thirdaicodegenerate.tool.BaseTool;
import com.ragdollcat.thirdaicodegenerate.tool.ToolManager;
import com.ragdollcat.thirdaicodegenerate.core.message.AiResponseMessage;
import com.ragdollcat.thirdaicodegenerate.core.message.StreamMessage;
import com.ragdollcat.thirdaicodegenerate.core.message.ToolExecutedMessage;
import com.ragdollcat.thirdaicodegenerate.core.message.ToolRequestMessage;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;

import java.util.HashSet;
import java.util.Objects;
import java.util.Set;


@Component
@Slf4j
public class ProjectFluxHandler {

    @Resource
    private BuildVueProject buildVueProject;

    @Resource
    private ToolManager toolManager;


    public Flux<String> handlerProject(Flux<String> flux, ChatHistoryService chatHistoryService , Long appId, User user, Integer version) {
        // 收集数据用于生成后端记忆格式
        StringBuilder chatHistoryStringBuilder = new StringBuilder();
        // 用于跟踪已经见过的工具ID，判断是否是第一次调用
        Set<String> seenToolIds = new HashSet<>();
        return flux
                .map(chunk -> {
                    // 解析每个 JSON 消息块
                    return handleJsonMessageChunk(chunk, chatHistoryStringBuilder,seenToolIds);
                })
                .filter(StrUtil::isNotEmpty) // 过滤空字串
                // 处理SSE格式化
                .doOnComplete(() -> {
                    // 流式响应完成后，添加 AI 消息到对话历史
                    String aiResponse = chatHistoryStringBuilder.toString();
                    chatHistoryService.saveChatHistory(aiResponse, appId, user.getId(), ChatHistoryMessageTypeEnum.AI.getValue());

//                    调用异步构建的方法
                    String path = AppConstant.SAVE_PATH + "vue_project_" + appId + "_" + version;
//                    buildVueProject.buildVueProjectAsync(path);
                    //改为同步构建
                    buildVueProject.buildVueProject(path);
                })
                .doOnError(error -> {
                    // 如果AI回复失败，也要记录错误消息
                    String errorMessage = "与AI对话错误：" + error.getMessage();
                    chatHistoryService.saveChatHistory(errorMessage, appId, user.getId(), ChatHistoryMessageTypeEnum.AI.getValue());
                });

    }


    /**
     * 解析并收集 TokenStream 数据
     * @param chunk 流式返回的片段
     * @param chatHistoryStringBuilder 封装后的对话记忆
     * @param seenToolIds 调用的工具Id
     */
    private String handleJsonMessageChunk(String chunk, StringBuilder chatHistoryStringBuilder, Set<String> seenToolIds) {
        // 解析 JSON
        StreamMessage streamMessage = JSONUtil.toBean(chunk, StreamMessage.class);
        StreamMessageTypeEnum typeEnum = StreamMessageTypeEnum.getEnumByValue(streamMessage.getType());
        switch (Objects.requireNonNull(typeEnum)) {
            case AI_RESPONSE -> {
                AiResponseMessage aiMessage = JSONUtil.toBean(chunk, AiResponseMessage.class);
                String data = aiMessage.getData();
                // 直接拼接响应
                chatHistoryStringBuilder.append(data);
                return data;
            }
            case TOOL_REQUEST -> {
                ToolRequestMessage toolRequestMessage = JSONUtil.toBean(chunk, ToolRequestMessage.class);
                String toolId = toolRequestMessage.getId();
                String name = toolRequestMessage.getName();
                // 检查是否是第一次看到这个工具 ID
                if (toolId != null && !seenToolIds.contains(toolId)) {
                    // 第一次调用这个工具，记录 ID 并完整返回工具信息
                    seenToolIds.add(toolId);
                    //从工具统一管理类中根据名称拿到对应的工具
                    BaseTool tool = toolManager.getTool(name);
                    //返回给页面选择工具的结果
                    return tool.chooseToolResult();
                } else {
                    // 不是第一次调用这个工具，直接返回空
                    return "";
                }
            }
            case TOOL_EXECUTED -> {
                ToolExecutedMessage toolExecutedMessage = JSONUtil.toBean(chunk, ToolExecutedMessage.class);
                //得到工具名称
                String name = toolExecutedMessage.getName();
                //解析出大模型调用工具后的arguments结果，是json的格式，这里用于返回给前端
                JSONObject jsonObject = JSONUtil.parseObj(toolExecutedMessage.getArguments());
                //从工具统一管理类中根据名称拿到对应的工具
                BaseTool tool = toolManager.getTool(name);
                //拿到工具的执行结果
                String result = tool.callToolResult(jsonObject);
//                String relativeFilePath = jsonObject.getStr("relativeFilePath");
//                String suffix = FileUtil.getSuffix(relativeFilePath);
//                String content = jsonObject.getStr("content");
//                String result = String.format("""
//                        [工具调用] 写入文件 %s
//                        ```%s
//                        %s
//                        ```
//                        """, relativeFilePath, suffix, content);
                // 输出前端和要持久化的内容
                String output = String.format("\n\n%s\n\n", result);
                chatHistoryStringBuilder.append(output);
                return output;
            }
            default -> {
                log.error("不支持的消息类型: {}", typeEnum);
                return "";
            }
        }

    }
}



